package com.aica.service.impl;

import com.aica.bo.UserMessageBo;
import com.aica.bo.response.PunchInRecordListBo;
import com.aica.bo.response.temp.PunchInRecordBo;
import com.aica.constant.ResultConstant;
import com.aica.constant.StringBuilderConstant;
import com.aica.entity.PunchInRecord;
import com.aica.mapper.PunchInRecordMapper;
import com.aica.service.PunchInRecordService;
import com.aica.service.UserService;
import com.aica.util.RedisUtil;
import com.aica.vo.ResultVo;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Date;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  打卡相关服务实现类
 * </p>
 *
 * @author by
 * @since 2021-07-20
 */
@Slf4j

@Service
public class PunchInRecordServiceImpl extends ServiceImpl<PunchInRecordMapper, PunchInRecord> implements PunchInRecordService {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private PunchInRecordMapper punchInRecordMapper;

    @Autowired
    private UserService userService;

    /**
     * 已测试
     */
    @Override
    public ResultVo<Object> rise(
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) {

        //获得用户名
        String username = usernamePasswordAuthenticationToken.getName();
        log.info(username + "正在进行起床打卡。。。");
        Integer userId = (Integer)redisUtil.get(StringBuilderConstant.USER_ID_ + username);

        //从缓存获取用户打卡记录
        UserMessageBo userMessageFromRedis = userService.getUserMessageFromRedis(username);
        List<PunchInRecord> punchInRecordList = userMessageFromRedis.getPunchInRecordList();

        //判断今天是否已经打卡
        PunchInRecord today = null;
        //当前系统时间,long类型
        long systemCurrentTimeMillis = System.currentTimeMillis();
        //当前系统日期，java.sql.Date类型
        Date systemCurrentDate = new Date(systemCurrentTimeMillis);
        //仅保留日期
        systemCurrentDate = Date.valueOf(systemCurrentDate.toString());
        //当前系统时间,java.sql.Timestamp类型
        Timestamp systemCurrentTimestamp = new Timestamp(systemCurrentTimeMillis);
        //无记录
        if(punchInRecordList==null || punchInRecordList.isEmpty()){
            //构建数据
            today = new PunchInRecord(
                    null, userId, systemCurrentDate,
                    systemCurrentTimestamp, null
            );
            //插入新一行数据，记录起床打卡
            int insert = punchInRecordMapper.insert(today);
            //刷新缓存数据
            UserMessageBo userMessageBo = userService.refreshUserMessageOnRedis(username);
            //返回结果
            return (insert==1 && userMessageBo!=null)? ResultConstant.OK:ResultConstant.SYSTEM_ERROR;
        }

        //比较已有记录中的最后一条记录
        PunchInRecord lastPunchInRecord = punchInRecordList.get(punchInRecordList.size() - 1);

        if((lastPunchInRecord !=null)
                && (systemCurrentDate.equals(lastPunchInRecord.getCurrentDateTime()))){
            //如果有当天记录，标记一下
            today = lastPunchInRecord;
        }

        //有当天记录，且已经打了起床卡，同时未打睡眠卡
        if(today!=null && today.getRiseTime()!=null && today.getSleepTime()==null){
            //返回当天已经进行了起床打卡
            return ResultConstant.HAVE_GOT_UP;
        }

        //无当天记录，或者已经打了起床卡，且当天有进行睡眠打卡
        //构建数据
        today = new PunchInRecord(
                null, userId, systemCurrentDate,
                systemCurrentTimestamp, null
        );
        //插入新一行数据，记录起床打卡
        int insert = punchInRecordMapper.insert(today);
        //刷新缓存数据
        UserMessageBo userMessageBo = userService.refreshUserMessageOnRedis(username);
        //返回结果
        return (insert==1 && userMessageBo!=null)? ResultConstant.OK:ResultConstant.SYSTEM_ERROR;

    }
    /**
     * 已测试
     */
    @Override
    public ResultVo<Object> sleep(
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) {

        //获得用户名
        String username = usernamePasswordAuthenticationToken.getName();
        log.info(username + "正在进行睡眠打卡。。。");
        Integer userId = (Integer)redisUtil.get(StringBuilderConstant.USER_ID_ + username);

        //从缓存获取用户打卡记录
        UserMessageBo userMessageFromRedis = userService.getUserMessageFromRedis(username);
        List<PunchInRecord> punchInRecordList = userMessageFromRedis.getPunchInRecordList();

        //判断今天是否已经打卡
        PunchInRecord today = null;
        //当前系统时间,long类型
        long systemCurrentTimeMillis = System.currentTimeMillis();
        //当前系统日期，java.sql.Date类型
        Date systemCurrentDate = new Date(systemCurrentTimeMillis);
        //仅保留日期
        systemCurrentDate = Date.valueOf(systemCurrentDate.toString());
        //当前系统时间,java.sql.Timestamp类型
        Timestamp systemCurrentTimestamp = new Timestamp(systemCurrentTimeMillis);
        //无记录
        if(punchInRecordList==null || punchInRecordList.isEmpty()){
            //构建数据
            today = new PunchInRecord(
                    null, userId, systemCurrentDate,
                    null, systemCurrentTimestamp
            );
            //插入新一行数据，记录睡眠打卡
            int insert = punchInRecordMapper.insert(today);
            //刷新缓存数据
            UserMessageBo userMessageBo = userService.refreshUserMessageOnRedis(username);
            //返回结果
            return (insert==1 && userMessageBo!=null)? ResultConstant.OK:ResultConstant.SYSTEM_ERROR;
        }
        //比较已有记录中的最后一条记录
        PunchInRecord lastPunchInRecord = punchInRecordList.get(punchInRecordList.size() - 1);

        if((lastPunchInRecord !=null)
                && (systemCurrentDate.equals(lastPunchInRecord.getCurrentDateTime()))){
            //如果有当天记录，标记一下
            today = lastPunchInRecord;
        }


        //有当天记录
        if(today!=null){
            //已经打睡眠卡
            if(today.getSleepTime()!=null){
                //返回当天已经进行了睡眠打卡
                return ResultConstant.HAVE_SLEEP;
            }
            //未进行睡眠打卡
            UpdateWrapper<PunchInRecord> updateWrapper = new UpdateWrapper<>();
            updateWrapper
                    .eq("id",today.getId())
                    .set("sleep_time",systemCurrentTimestamp);
            int update = punchInRecordMapper.update(new PunchInRecord(), updateWrapper);
            //刷新缓存数据
            UserMessageBo userMessageBo = userService.refreshUserMessageOnRedis(username);
            //返回结果
            return (update==1 && userMessageBo!=null)? ResultConstant.OK:ResultConstant.SYSTEM_ERROR;
        }

        //无当天记录
        //构建数据
        today = new PunchInRecord(
                null, userId, systemCurrentDate,
                null, systemCurrentTimestamp
        );
        //插入新一行数据，记录睡眠打卡
        int insert = punchInRecordMapper.insert(today);
        //刷新缓存数据
        UserMessageBo userMessageBo = userService.refreshUserMessageOnRedis(username);
        //返回结果
        return (insert==1 && userMessageBo!=null)? ResultConstant.OK:ResultConstant.SYSTEM_ERROR;
    }
    /**
     * 已测试
     */
    @Override
    public ResultVo<Object> history(
            UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken) {

        //获得用户名
        String username = usernamePasswordAuthenticationToken.getName();
        log.info(username + "正在进行打卡记录查询。。。");

        //从缓存获取用户打卡记录
        UserMessageBo userMessageFromRedis = userService.getUserMessageFromRedis(username);
        List<PunchInRecord> punchInRecordList = userMessageFromRedis.getPunchInRecordList();
        //无打卡记录
        if(punchInRecordList==null||punchInRecordList.isEmpty()){
            return ResultConstant.DO_NOT_HAVE_PUNCH_IN_RECORD;
        }
        //结果封装
        ArrayList<PunchInRecordBo> punchInRecordBoList = new ArrayList<>();
        for (PunchInRecord p : punchInRecordList) {
            punchInRecordBoList.add(
                    new PunchInRecordBo(
                            p.getId(),
                            p.getCurrentDateTime(),
                            p.getRiseTime()==null?null:p.getRiseTime().getTime(),
                            p.getSleepTime()==null?null:p.getSleepTime().getTime()
                    )
            );
        }

        return new ResultVo<>(new PunchInRecordListBo(punchInRecordBoList));
    }
}
